/**
 * @file bsp_lis3mdl.c
 * @author yuchenghao (yuchenghao@mail.ncut.edu.cn)
 * @brief 适用于实验室g431开发板的lis3mdl板级支持包
 * @version 0.1
 * @date 2024-04-26
 *
 * @copyright Copyright (c) 2024
 *
 */
#include "bsp_lis3mdl.h"
#include "lis3mdl_reg.h" //st官方下载的寄存器表，https://github.com/STMicroelectronics/lis3mdl-pid
#include "i2c.h"
#include "more_printf.h"
static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp, uint16_t len)
{
    reg |= 0x80;
    HAL_I2C_Mem_Write(handle, LIS3MDL_I2C_ADD_L, reg, I2C_MEMADD_SIZE_8BIT, (uint8_t *)bufp, len, 1000);
    return 0;
}
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{

    reg |= 0x80;
    HAL_I2C_Mem_Read(handle, LIS3MDL_I2C_ADD_L, reg, I2C_MEMADD_SIZE_8BIT, bufp, len, 1000);
    return 0;
}
static void platform_delay(uint32_t ms)
{

    HAL_Delay(ms);
}
/**
 * @brief 读取磁力计的id号
 *
 * @return uint8_t id号
 */
uint8_t lis3mdl_get_chip_id(void)
{

    stmdev_ctx_t dev_ctx;
    uint8_t whoamI;
    /* Initialize mems driver interface */
    dev_ctx.write_reg = platform_write;
    dev_ctx.read_reg = platform_read;
    dev_ctx.mdelay = platform_delay;
    dev_ctx.handle = &hi2c1;
    /* Check device ID */
    lis3mdl_device_id_get(&dev_ctx, &whoamI);
    return whoamI;
}
stmdev_ctx_t dev_ctx;
/**
 * @brief 初始化代码，会返回一个控制块地址
 * 
 * @return stmdev_ctx_t 控制块
 */
void lis3mdl_init(void)
{
    uint8_t rst;
    dev_ctx.write_reg = platform_write;
    dev_ctx.read_reg = platform_read;
    dev_ctx.mdelay = platform_delay;
    dev_ctx.handle = &hi2c1;
    lis3mdl_reset_set(&dev_ctx, PROPERTY_ENABLE);

    do
    {
        lis3mdl_reset_get(&dev_ctx, &rst);
    } while (rst);

    /* Enable Block Data Update */
    lis3mdl_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);//
    /* Set Output Data Rate */
    lis3mdl_data_rate_set(&dev_ctx, LIS3MDL_HP_20Hz);
    /* Set full scale */
    lis3mdl_full_scale_set(&dev_ctx, LIS3MDL_16_GAUSS);
    /* Enable temperature sensor */
    lis3mdl_temperature_meas_set(&dev_ctx, PROPERTY_ENABLE);
    /* Set device in continuous mode */
    lis3mdl_operating_mode_set(&dev_ctx, LIS3MDL_CONTINUOUS_MODE);
}
/**
 * @brief 读取磁力计的数据
 * 
 * @param dev_ctx 控制句柄
 * @param mag_data 磁力计数据
 * @return uint8_t 1：成功 0：数据未准备好
 */
uint8_t lis3mdl_read_data(mag_data_t *mag_data)
{
    uint16_t data_raw_magnetic[3];
    uint8_t reg;
    /* Read output only if new value is available */
    lis3mdl_mag_data_ready_get(&dev_ctx, &reg);

    if (reg)
    {
        /* Read magnetic field data */
        memset(data_raw_magnetic, 0x00, 3 * sizeof(int16_t));
        lis3mdl_magnetic_raw_get(&dev_ctx, data_raw_magnetic);
        mag_data->mag_x = 1000 * lis3mdl_from_fs16_to_gauss(
                                     data_raw_magnetic[0]);
        mag_data->mag_y = 1000 * lis3mdl_from_fs16_to_gauss(
                                     data_raw_magnetic[1]);
        mag_data->mag_z = 1000 * lis3mdl_from_fs16_to_gauss(
                                     data_raw_magnetic[2]);
        mag_data->mag_x_raw = data_raw_magnetic[0];
        mag_data->mag_y_raw = data_raw_magnetic[1];
        mag_data->mag_z_raw = data_raw_magnetic[2];
        return 1;
    }
    else
    {
        return 0;
    }
}